use crate::app::cluster::ingress_controller::IngController;
use crate::app::cluster::SvcController;
use crate::app::core::ControlEventDispenser;
use crate::config::{IngressLister, ServicesLister};
use anyhow::Result;
use kube::Client;
use std::sync::Arc;

pub struct Cluster {
    client: Client,
    ing_lister_cfg: IngressLister,
    svc_lister_cfg: ServicesLister,
}
impl Cluster {
    pub async fn try_default(
        ing_lister_cfg: IngressLister,
        svc_lister_cfg: ServicesLister,
    ) -> Result<Self> {
        let client = Client::try_default().await?;
        Ok(Self {
            client,
            ing_lister_cfg,
            svc_lister_cfg,
        })
    }

    pub fn active_service_watch(&self, dispenser: Arc<dyn ControlEventDispenser>) -> Result<()> {
        let svcc = SvcController::new(self.client.clone(), self.svc_lister_cfg.clone());
        svcc.watch_service(dispenser.clone())
    }

    pub fn active_ingress_watch(&self, dispenser: Arc<dyn ControlEventDispenser>) -> Result<()> {
        let ingc = IngController::new(self.client.clone(), self.ing_lister_cfg.clone());
        ingc.watch_ingress(dispenser.clone())
    }
}

#[cfg(test)]
mod test {
    use super::Cluster;
    use crate::app::core::{ControlEvent, ControlEventDispenser, OptResponse};
    use crate::config::{IngressLister, ServicesLister};
    use std::sync::Arc;

    struct Dispenser;

    #[async_trait::async_trait]
    impl ControlEventDispenser for Dispenser {
        async fn dispatch(&self, ce: ControlEvent) -> anyhow::Result<Option<OptResponse>> {
            wd_log::log_info_ln!("接收到一个服务内事件：{}", ce.kind);
            Ok(None)
        }
    }

    #[tokio::test]
    async fn test_service() {
        let ing_cfg = IngressLister::default();
        let mut svc_cfg = ServicesLister::default();
        svc_cfg.namespaces = Some(String::from("default"));
        let cluster = Cluster::try_default(ing_cfg, svc_cfg)
            .await
            .expect("连接集群失败");
        cluster
            .active_service_watch(Arc::new(Dispenser))
            .expect("监听集群services失败");
        tokio::time::sleep(tokio::time::Duration::from_secs(10000)).await;
    }
}
